#include "xy_wdf.h"
#include <algorithm>

XY_Wdf::XY_Wdf()
{
	_fileCount = 0;
	_fileList = nullptr;
}

XY_Wdf::~XY_Wdf()
{
	Close();
}

bool XY_Wdf::Open(const char* fileName)
{
	if (IsOpen()) Close();
	_file.open(fileName, std::ios::binary);
	if (!IsOpen()) return false;
	char buf[256];
	_file.read(buf, 4);
	if (*(uint32_t*)buf != 0x57444650) {
		_file.close();
		return false;
	}
	_file.read(buf, 4);
	_fileCount = *(uint32_t*)buf;
	_file.read(buf, 4);
	uint32_t listOffset = *(uint32_t*)buf;
	_file.seekg(listOffset, std::ifstream::beg);
	_fileList = new WdfFileHeader[_fileCount];
	_file.read((char*)_fileList, _fileCount * sizeof(uint32_t) * 4);
	std::sort(_fileList, _fileList + _fileCount);
	return true;
}

bool XY_Wdf::IsOpen(void) const
{
	return _file.is_open();
}

void XY_Wdf::Close(void)
{
	if (_fileList) {
		delete[] _fileList;
		_fileList = nullptr;
	}
	_file.close();
}

XY_Wdf::WdfFile XY_Wdf::GetFile(uint32_t uid)
{
	WdfFile was;
	int begin, end, middle;
	begin = 0, end = _fileCount - 1;
	while (begin <= end)
	{
		middle = (begin + end) >> 1;
		if (_fileList[middle].uid == uid) {
			const auto* wasfile = &_fileList[middle];
			was.size = wasfile->size;
			was.pData = new unsigned char[was.size];
			_file.seekg(wasfile->offset, std::ifstream::beg);
			_file.read((char*)was.pData, was.size);
			break;
		}
		else if (_fileList[middle].uid < uid) begin = middle + 1;
		else end = middle - 1;
	}
	return was;
}